﻿/*
The name of the cs = Pasteur.
Change Pasteur everywhere with the name of your cs files
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using Bots.BGBuddy.Helpers;
using System.Threading;
using Styx;
using Styx.CommonBot.POI;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.Helpers;
using Styx.MemoryManagement;
using System.Diagnostics;
using Styx.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Styx.TreeSharp;

namespace Pasteur
{
    class Classname : CombatRoutine
    {
        public override sealed string Name { get { return "Shadow Priest CC by Pasterke"; } } // Show version for class

        public override WoWClass Class { get { return WoWClass.Priest; } } // change to relevant class

        private static LocalPlayer Me { get { return StyxWoW.Me; } }

        private void slog(string format, params object[] args) //use for slogging
        {
            Logging.Write(format, args);
        }

        public override bool WantButton{ get { return true; } }
		
		public Styx.WoWInternals.WoWGroupInfo GroupInfo { get; set; }

        public string LastSpell = "";
         
		public override void OnButtonPress() 
        {
            Pasteur.Form1 myConfig = new Pasteur.Form1();
            myConfig.ShowDialog();
			// remove comment to show Form
        }
        public override void Initialize()
        {
            Updater.CheckForUpdate();
        }
		
		#region CountPlayerBuffs or CountTargetBuffs
		
		public static uint PlayerCountBuff(string name)
        {
            return GetAuraStack(Me, name, true);
        }
        public static uint TargetCountDebuff(string name)
        {
            return GetAuraStack(Me.CurrentTarget, name, true);
        }
		 
        public static uint GetAuraStack(WoWUnit unit, string auraName, bool fromMyAura)
        {
            if (unit != null)
            {
                WoWAura aura;
                if (unit.Auras.TryGetValue(auraName, out aura))
                {
                    var returnvalue = (!fromMyAura || aura.CreatorGuid == Me.Guid) && aura.StackCount > 0;
                    return returnvalue ? aura.StackCount : 0;
                }
                return 0;
            }
            return 0;
        }
		
		#endregion CountPlayerBuffs or CountTargetBuffs

        
        PasteurSpellId mySpellInts = new PasteurSpellId();
        PasteurBagItems myBagItems = new PasteurBagItems();
        PasteurTrinkets myTrinkets = new PasteurTrinkets();
        Stopwatch vttimer = new Stopwatch();
        Stopwatch swptimer = new Stopwatch();
        Stopwatch mstimer = new Stopwatch();

        string welkeSpell
        {
            get
            {
                string useSpell = "";
                if (Me.Level < 3) { useSpell = "Smite"; }
                if (Me.Level >= 3) { useSpell = "Shadow Word: Pain";}
                //if (Me.Level >= 44) { useSpell = "Mind Spike"; }
                return useSpell;
            }
        }
        private double naarTarget
        {
            get
            {
                double pullenTarget = 0;
                pullenTarget = SpellManager.Spells[welkeSpell].MaxRange - 1;
                return pullenTarget;
            }
        }

        private double targetDistance
        {
            get
            {
                return Me.GotTarget ? Me.CurrentTarget.Distance : uint.MaxValue - 1;
            }
        }
        private static Stopwatch pullTimer = new Stopwatch();
        private static Stopwatch fightTimer = new Stopwatch();
        private static ulong lastGuid = 0;

        #region CC_Begin


        public override bool NeedRest
		{ 
			get 
			{ 
				if ((Me.HealthPercent <= PasteurSettings.myPrefs.renew
                    || Me.HealthPercent <= PasteurSettings.myPrefs.flash)
                    || Me.ManaPercent <= PasteurSettings.myPrefs.drinkmana
                    && Me.IsAlive)
                {
                    return true;
                }
				return false; 
			} 
		}

        public override void Rest() // after combat we use renew, or flash heal or normal food to regain life.
		{ 
			if (Me.HealthPercent <= PasteurSettings.myPrefs.renew
                && Me.HealthPercent > PasteurSettings.myPrefs.flash
                && Me.IsAlive)
            {
                if (SpellManager.CanCast(mySpellInts.renew) && !Me.HasAura(mySpellInts.renew))
                {
                    SpellManager.Cast(mySpellInts.renew);
                    Logging.Write("Renew after combat");
                }
            }
            else if (Me.HealthPercent <= PasteurSettings.myPrefs.flash && Me.IsAlive)
            {
                if (SpellManager.CanCast(mySpellInts.flashheal))
                {
                    SpellManager.Cast(mySpellInts.flashheal);
                    Logging.Write("Flash Heal after combat");
                }
            }
            else if (!SpellManager.CanCast("Renew") || !SpellManager.CanCast("Flash Heal") && Me.IsAlive) 
            {
                Styx.CommonBot.Rest.Feed();
            }
            if (Me.ManaPercent <= PasteurSettings.myPrefs.drinkmana && Me.IsAlive)
            {
                Styx.CommonBot.Rest.Feed();
            }
		}

        #endregion

        #region Pull

        public override void Pull() 
		{
            if (!PasteurSettings.myPrefs.DisableAllMovement)
            {
                EnsureTarget();
                if (Battlegrounds.IsInsideBattleground)
                {
                    if (Me.GotTarget &&
                        Me.CurrentTarget.IsPet)
                    {
                        Blacklist.Add(Me.CurrentTarget, TimeSpan.FromDays(1));
                        Me.ClearTarget();
                    }

                    if (Me.GotTarget && Me.CurrentTarget.Mounted)
                    {
                        Blacklist.Add(Me.CurrentTarget, TimeSpan.FromMinutes(1));
                        Me.ClearTarget();
                    }
                }

                if (Me.CurrentTarget.Guid != lastGuid)
                {
                    fightTimer.Reset();
                    lastGuid = Me.CurrentTarget.Guid;
                    slog("Killing " + Me.CurrentTarget.Name + " at distance " + System.Math.Round(targetDistance).ToString() + ".");
                    pullTimer.Reset();
                    pullTimer.Start();

                }
                else
                {
                    if (pullTimer.ElapsedMilliseconds > 30 * 1000)
                    {
                        slog("Cannot pull " + Me.CurrentTarget.Name + " now.  Blacklist for 3 minutes.");
                        Blacklist.Add(Me.CurrentTarget.Guid, System.TimeSpan.FromMinutes(3));
                    }
                }

                if (Me.CurrentTarget.Distance > naarTarget)
                {
                    Navigator.MoveTo(attackPoint);
                    return;
                }
                else
                {
                    if (Me.IsMoving)
                    {
                        WoWMovement.MoveStop();
                    }
                    Me.CurrentTarget.Face();
                    if (PlayerCountBuff("Shadow Orb") == 3)
                    {
                        DevouringPlague();
                    }
                    else if (Me.Level < 3) 
                    { 
                        Smite(); 
                    }
                    else if (Me.Level >= 3) 
                    { 
                        ShadowWordPain();
                    }
                     
                }
            }
		}

        #endregion

        #region Pull Buffs

        public override bool NeedPullBuffs { get { return false; } }

        public override void PullBuff() { }

        #endregion

        #region Pre Combat Buffs

        public override bool NeedPreCombatBuffs { 
            get 
            {
                if (!Me.IsDead || !Me.IsGhost)
                {
                    PowerWordFortitude();
                    InnerFire();
                    ShadowForm();
                    //myBagItems.AlchemistFlask();
                }
                return false; 
            } 
        }

        public override void PreCombatBuff()
        {

        }

        #endregion

        #region Combat Buffs

        public override bool NeedCombatBuffs 
        { 
            get 
            {
                PowerWordFortitude();
                InnerFire();
                ShadowForm();
                return false; 
            } 
        }

        public override void CombatBuff() { }

        #endregion

        #region Heal

        public override bool NeedHeal { get { return false; } }

        public override void Heal() { }

        #endregion

        #region Falling

        public void HandleFalling() { }

        #endregion

        #region Combat

        public override void Combat()
        {
            if (!PasteurSettings.myPrefs.DisableAllMovement)
            {
                EnsureTarget();
                if (Me.GotTarget && Me.CurrentTarget.Distance > naarTarget)
                {
                    Navigator.MoveTo(attackPoint);
                    return;
                }
                if (Me.IsMoving)
                {
                    WoWMovement.MoveStop();
                }
                if (Me.CurrentTarget.IsDead)
                {
                    Me.ClearTarget();
                }
                if (!PasteurSettings.myPrefs.DisableFacing)
                {
                    Me.CurrentTarget.Face();
                }
                if (Me.Level >= 74 && Adds())
                {

                    myBagItems.AlchemistFlask();
                    myBagItems.HealthStone();
                    myBagItems.LifeSpirit();
                    myBagItems.WaterSpirit();
                    PowerWordShield();
                    VampiricEmbrace();
                    FiendBinder();
                    Renew();
                    FlashHeal();
                    Dispersion();
                    FearWard();
                    ShadowForm();
                    ShadowDeath();
                    PsychicScream();
                    MindSear();
                }
                else
                {
                    myBagItems.AlchemistFlask();
                    myBagItems.HealthStone();
                    myBagItems.LifeSpirit();
                    myBagItems.WaterSpirit();
                    Silence();
                    PowerWordShield();
                    Smite();
                    VampiricEmbrace();
                    FiendBinder();
                    Renew();
                    FlashHeal();
                    Dispersion();
                    FearWard();
                    ShadowDeath();
                    DevouringPlague();
                    PsychicScream();
                    Mindspike();
                    VampiricTouch();
                    ShadowWordPain();
                    FeindBinderDps();
                    Tier1();
                    Tier3();
                    Tier4();
                    Tier5();
                    Tier6();
                    LifeBlood();
                    MindBlast();
                    MindFlay();
                }
            }
            else if (PasteurSettings.myPrefs.DisableAllMovement)
            {
                if (!PasteurSettings.myPrefs.DisableFacing)
                {
                    Me.CurrentTarget.Face();
                }
                if (Me.Level >= 74 && Adds())
                {

                    myBagItems.AlchemistFlask();
                    myBagItems.HealthStone();
                    myBagItems.LifeSpirit();
                    myBagItems.WaterSpirit();
                    PowerWordShield();
                    VampiricEmbrace();
                    FiendBinder();
                    Renew();
                    FlashHeal();
                    Dispersion();
                    FearWard();
                    ShadowDeath();
                    PsychicScream();
                    MindSear();
                }
                else
                {
                    myBagItems.AlchemistFlask();
                    myBagItems.HealthStone();
                    myBagItems.LifeSpirit();
                    myBagItems.WaterSpirit();
                    Silence();
                    PowerWordShield();
                    Smite();
                    VampiricEmbrace();
                    FiendBinder();
                    Renew();
                    FlashHeal();
                    Dispersion();
                    FearWard();
                    ShadowDeath();
                    DevouringPlague();
                    PsychicScream();
                    Mindspike();
                    VampiricTouch();
                    ShadowWordPain();
                    FeindBinderDps();
                    Tier1();
                    Tier3();
                    Tier4();
                    Tier5();
                    Tier6();
                    LifeBlood();
                    MindBlast();
                    MindFlay();
                }
            }
        }
        #endregion Combat


        #region Priest Spells


        private void AutoAttack()
        {
            if (!Me.IsAutoAttacking)
            {
                Lua.DoString("StartAttack()");
            }

        }
        public bool LifeBlood()
        {
            if (PasteurSettings.myPrefs.UseLifeblood)
            {
                if (SpellManager.Spells["Lifeblood"].CooldownTimeLeft.TotalSeconds < 1)
                {
                    SpellManager.Cast("Lifeblood");
                    Logging.Write(Colors.Yellow, "Lifeblood");
                    LastSpell = "LFB";
                    return true;
                }
            }
            return false;
        }
        public bool Smite()
        {
            if (Me.Level < 10 && SpellManager.CanCast(mySpellInts.smite) && !SpellManager.GlobalCooldown)
            {
                SpellManager.Cast(mySpellInts.smite);
                Logging.Write("Smite");
                LastSpell = "smite";
                return true;
            }
            return false;
        }
        public bool Mindspike()
        {
            if (SpellManager.CanCast(mySpellInts.MSP) && Me.HasAura("Surge of Darkness"))
            {
                SpellManager.Cast(mySpellInts.MSP);
                Logging.Write("Mind Spike");
                LastSpell = "MSP";
                return true;
            }
            return false;
        }
        public bool DevouringPlague()
        {
            if (SpellManager.CanCast(mySpellInts.DP) && (Me.GroupInfo.IsInParty || Me.IsInInstance)
                && PlayerCountBuff("Shadow Orb") >= 3
                )
            {
                SpellManager.Cast(mySpellInts.DP);
                Logging.Write("Devouring Plague");
                LastSpell = "DP";
                return true;
            }
            else if (SpellManager.CanCast(mySpellInts.DP) && (!Me.GroupInfo.IsInParty || !Me.IsInInstance)
                && PlayerCountBuff("Shadow Orb") >= PasteurSettings.myPrefs.partyplague
                && Me.CurrentTarget.HealthPercent >= PasteurSettings.myPrefs.devouringplague
                && !Me.CurrentTarget.IsTotem
                )
            {
                SpellManager.Cast(mySpellInts.DP);
                Logging.Write("Devouring Plague");
                LastSpell = "DP";
                return true;
            }
            return false;
        }
		public bool MindBlast()
        {
            if (SpellManager.CanCast(mySpellInts.MB) && !SpellManager.GlobalCooldown )
            {  
                SpellManager.Cast(mySpellInts.MB);
                Logging.Write("Mind Blast");
                LastSpell = "MB";
                return true;
            }
            return false;
        }
		public bool ShadowWordPain()
        {
            if (SpellManager.CanCast(mySpellInts.SWP) && !Me.CurrentTarget.IsTotem )
                
            {
                if ((!swptimer.IsRunning || swptimer.ElapsedMilliseconds > 14000)
                    || (swptimer.IsRunning && !Me.CurrentTarget.HasAura(mySpellInts.SWP))
                    && LastSpell != "SWP")
                {
                    swptimer.Reset();
                    swptimer.Start();
                    SpellManager.Cast(mySpellInts.SWP);
                    Logging.Write("Shadow Word Pain");
                    LastSpell = "SWP";
                    return true;
                }
            }
            return false;
        }
        public bool VampiricTouch()
        {
            if (SpellManager.CanCast(mySpellInts.VT)
                && Me.CurrentTarget.HealthPercent >= PasteurSettings.myPrefs.vamirictouch
                && !Me.CurrentTarget.IsTotem
                && LastSpell != "VT")
            {
                if ((!vttimer.IsRunning || vttimer.ElapsedMilliseconds > 10000)
                    || (vttimer.ElapsedMilliseconds > 2000 && !Me.CurrentTarget.HasAura(mySpellInts.VT)))
                {
                    vttimer.Reset();
                    vttimer.Start();
                    SpellManager.Cast(mySpellInts.VT);
                    Logging.Write("Vampiric Touch");
                    LastSpell = "VT";
                    return true;
                }
            }
            return false;
        }
        public bool ShadowDeath()
        {
            if (SpellManager.CanCast(mySpellInts.SWD) && Me.CurrentTarget.HealthPercent < 20 )
            {
                SpellManager.Cast(mySpellInts.SWD);
                Logging.Write("Shadow Word Death");
                LastSpell = "SWD";
                return true;
            }
            return false;
        }
        
        public bool MindFlay()
        {
            if (SpellManager.CanCast(mySpellInts.MF)
                && !Me.IsChanneling 
                && Me.CurrentCastTimeLeft.TotalMilliseconds < 700
                )
            {
                SpellManager.Cast(mySpellInts.MF);
                Logging.Write("Mind Flay");
                LastSpell = "MF";
                return true;
            }
            return false;
        }
        public bool MindSear()
        {
            if (PasteurSettings.myPrefs.NoMindSearOnBosses && IsTargetBoss())
            {
                return false;
            }
            else if (PasteurSettings.myPrefs.MindSear == "party")
            {
                if (SpellManager.CanCast(mySpellInts.MS) && !Me.IsChanneling && Adds())
                {
                    if (!mstimer.IsRunning || mstimer.ElapsedMilliseconds > 4600)
                    {
                        mstimer.Reset();
                        mstimer.Start();
                        SpellManager.Cast(mySpellInts.MS);
                        Logging.Write("Mind Sear only in party");
                        LastSpell = "MS";
                        return true;
                    }
                }
            }
            else if (PasteurSettings.myPrefs.MindSear == "always")
            {
                if (SpellManager.CanCast(mySpellInts.MS) && !Me.IsChanneling && Adds())
                {
                    if (!mstimer.IsRunning || mstimer.ElapsedMilliseconds > 4600)
                    {
                        mstimer.Reset();
                        mstimer.Start();
                        SpellManager.Cast(mySpellInts.MS);
                        Logging.Write("Always cast Mind Sear");
                        LastSpell = "MS";
                        return true;
                    }
                }
            }
                return false;
        }
        public bool FeindBinderDps()
        {
            if(SpellManager.CanCast(mySpellInts.shadowfiend) && !SpellManager.GlobalCooldown
                && (IsTargetBoss() || Me.ManaPercent <= PasteurSettings.myPrefs.ShadowfeindMindbender))
            {
                SpellManager.Cast(mySpellInts.shadowfiend);
                Logging.Write(Colors.OrangeRed, "Shadowfiend for DPS");
                LastSpell = "fiend";
                return true;
            }
            else if (SpellManager.CanCast(mySpellInts.MiB) && !SpellManager.GlobalCooldown
                && (IsTargetBoss() || Me.ManaPercent <= PasteurSettings.myPrefs.ShadowfeindMindbender))
            {
                SpellManager.Cast(mySpellInts.MiB);
                Logging.Write(Colors.OrangeRed, "Mindbender for DPS");
                LastSpell = "fiend";
                return true;
            }
            return false;
        }
        public bool FearWard()
        {
            if (SpellManager.CanCast(mySpellInts.fearward) && !SpellManager.GlobalCooldown
                && PasteurSettings.myPrefs.fearward)
            {
                SpellManager.Cast(mySpellInts.fearward);
                Logging.Write("Fear Ward");
                LastSpell = "ward";
                return true;
            }
            return false;
        }
        public bool PsychicScream()
        {
            if (SpellManager.CanCast(mySpellInts.psychicscream) && !SpellManager.GlobalCooldown
                && mobCounting > 1 && mobCounting < PasteurSettings.myPrefs.Aoe
                && !PasteurSettings.myPrefs.psyscream)
            {
                SpellManager.Cast(mySpellInts.psychicscream);
                Logging.Write(Colors.Coral, "Psychic Scream");
                LastSpell = "psy";
                return true;
            }
            return false;
        }
        public bool Silence()
        {
            if (SpellManager.CanCast(mySpellInts.silence) && !SpellManager.GlobalCooldown
                && Me.CurrentTarget != null
                && (Me.CurrentTarget.IsCasting && Me.CurrentTarget.CanInterruptCurrentSpellCast)
                && PasteurSettings.myPrefs.UseSilence
                && !Adds())
            {
                SpellManager.Cast(mySpellInts.silence);
                Logging.Write("Silence to interrupt");
                LastSpell = "silence";
                return true;

            }
            return false;
        }
        #endregion  Priest Spells 

        #region Talents
        public bool Tier1()
        {
            switch (PasteurSettings.myPrefs.Tier1)
            {
                case "Psyfiend" :
                    if (PasteurSettings.myPrefs.chckTier1 && IsTargetBoss())
                    {
                        if (SpellManager.CanCast(mySpellInts.psyfiend) && !SpellManager.GlobalCooldown
                            && Adds())
                        {
                            SpellManager.Cast(mySpellInts.psyfiend);
                            Logging.Write(Colors.Coral, "Psyfiend on Bosses");
                            return true;
                        }
                    }
                    else if(!PasteurSettings.myPrefs.chckTier1)
                    {
                        if (SpellManager.CanCast(mySpellInts.psyfiend) && !SpellManager.GlobalCooldown
                            && Adds())
                        {
                            SpellManager.Cast(mySpellInts.psyfiend);
                            Logging.Write(Colors.Coral, "Psyfiend on Bosses");
                            return true;
                        }
                    }
                    break;
                case "Void Tendrils" :
                    if (PasteurSettings.myPrefs.chckTier1 && IsTargetBoss())
                    {
                        if (SpellManager.CanCast(mySpellInts.voidtendrils) && !SpellManager.GlobalCooldown
                            && Adds())
                        {
                            SpellManager.Cast(mySpellInts.voidtendrils);
                            if (PasteurSettings.myPrefs.tendrillscreamcombo)
                            {
                                if (SpellManager.CanCast(mySpellInts.psychicscream) && !SpellManager.GlobalCooldown)
                                {
                                    SpellManager.Cast(mySpellInts.psychicscream);
                                    Logging.Write(Colors.Coral, "Psychic Scream with Tendrills");
                                }
                            }
                            Logging.Write(Colors.Coral, "Void Tendrils on Bosses");
                            return true;
                        }
                    }
                    else if(!PasteurSettings.myPrefs.chckTier1)
                    {
                        if (SpellManager.CanCast(mySpellInts.voidtendrils) && !SpellManager.GlobalCooldown
                            && Adds())
                        {
                            SpellManager.Cast(mySpellInts.voidtendrils);
                            if (PasteurSettings.myPrefs.tendrillscreamcombo)
                            {
                                if (SpellManager.CanCast(mySpellInts.psychicscream) && !SpellManager.GlobalCooldown)
                                {
                                    SpellManager.Cast(mySpellInts.psychicscream);
                                    Logging.Write(Colors.Coral, "Psychic Scream with Tendrills");
                                }
                            }
                            Logging.Write(Colors.Coral, "Always use talent Void Tendrills");
                            return true;
                        }
                    }
                    break;
            }
            return false;
        }
        public bool Tier3()
        {
            switch (PasteurSettings.myPrefs.Tier3)
            {
                case "Darkness Light":
                    return false;

                case "Mindbender":
                    if (PasteurSettings.myPrefs.chckTier3 && (IsTargetBoss() || Me.ManaPercent <= PasteurSettings.myPrefs.ShadowfeindMindbender))
                    {
                        if (SpellManager.CanCast(mySpellInts.MiB) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.MiB);
                            Logging.Write(Colors.Coral, "Mindbender talent on Boss");
                            return true;
                        }
                    }
                    else if(!PasteurSettings.myPrefs.chckTier3)
                    {
                        if (SpellManager.CanCast(mySpellInts.MiB) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.MiB);
                            Logging.Write(Colors.Coral, "Always use talent Mindbender");
                            return true;
                        }
                    }
                    break;
                case "Power Word Solace":
                    if (PasteurSettings.myPrefs.chckTier3 && IsTargetBoss())
                    {
                        if (SpellManager.CanCast(mySpellInts.powerwordsolace) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.powerwordsolace);
                            Logging.Write(Colors.Coral, "Power Word Solace talent on Boss");
                            return true;
                        }
                    }
                    else if(!PasteurSettings.myPrefs.chckTier3)
                    {
                        if (SpellManager.CanCast(mySpellInts.powerwordsolace) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.powerwordsolace);
                            Logging.Write(Colors.Coral, "Always use talent Power Word Solace");
                            return true;
                        }
                    }
                    break;
            }
            return false;
        }
        public bool Tier4()
        {
            switch (PasteurSettings.myPrefs.Tier4)
            {
                case "Angelic Bulwark":
                    return false;

                case "Desperate Prayer" :
                    if (PasteurSettings.myPrefs.chckTier4 && IsTargetBoss())
                    {
                        if (SpellManager.CanCast(mySpellInts.desperateprayer) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.desperateprayer);
                            Logging.Write(Colors.Coral, "Talent Desperate Prayer on Boss");
                            return true;
                        }
                    }
                    else if(!PasteurSettings.myPrefs.chckTier4)
                    {
                        if (SpellManager.CanCast(mySpellInts.desperateprayer) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.desperateprayer);
                            Logging.Write(Colors.Coral, "Always use talent Desperate Prayer");
                            return true;
                        }
                    }
                    break;

                case "Spectral Guise":
                    if (PasteurSettings.myPrefs.chckTier4 && IsTargetBoss())
                    {
                        if (SpellManager.CanCast(mySpellInts.spectralguise) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.spectralguise);
                            Logging.Write(Colors.Coral, "Talent Spectral Guise on Boss");
                            return true;
                        }
                    }
                    else if(!PasteurSettings.myPrefs.chckTier4)
                    {
                        if (SpellManager.CanCast(mySpellInts.spectralguise) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.spectralguise);
                            Logging.Write(Colors.Coral, "Always use talent Spectral Guise");
                            return true;
                        }
                    }
                    break;
            }
            return false;
        }
        public bool Tier5()
        {
            switch (PasteurSettings.myPrefs.Tier5)
            {
                case "Twist of Fate":
                    return false;
             
                case "Divine Insight" :
                    return false;

                case "Power Infusion" :
                    if (PasteurSettings.myPrefs.chckTier5 && IsTargetBoss())
                    {
                        if (SpellManager.CanCast(mySpellInts.powerinfusion) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.powerinfusion);
                            Logging.Write(Colors.Coral, "Talent Power Infusion on Boss");
                            return true;
                        }
                    }
                    else if(!PasteurSettings.myPrefs.chckTier5)
                    {
                        if (SpellManager.CanCast(mySpellInts.powerinfusion) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.powerinfusion);
                            Logging.Write(Colors.Coral, "Always use talent Power Infusion");
                            return true;
                        }
                    }
                    break;

            }
            return false;
        }
        public bool Tier6()
        {
            switch (PasteurSettings.myPrefs.Tier6)
            {
                case "Cascade" :
                    if (PasteurSettings.myPrefs.chckTier6 && IsTargetBoss())
                    {
                        if (SpellManager.CanCast(mySpellInts.cascade) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.cascade);
                            Logging.Write(Colors.Coral, "Talent Cascade on Boss");
                            return true;
                        }
                    }
                    else if(!PasteurSettings.myPrefs.chckTier6)
                    {
                        if (SpellManager.CanCast(mySpellInts.cascade) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.cascade);
                            Logging.Write(Colors.Coral, "Always use Talent Cascade");
                            return true;
                        }
                    }
                    break;
                case "Divine Star" :
                    if (PasteurSettings.myPrefs.chckTier6 && IsTargetBoss())
                    {
                        if (SpellManager.CanCast(mySpellInts.divinestar) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.divinestar);
                            Logging.Write(Colors.Coral, "Talent Divine Star on Boss");
                            return true;
                        }
                    }
                    else if(!PasteurSettings.myPrefs.chckTier6)
                    {
                        if (SpellManager.CanCast(mySpellInts.divinestar) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.divinestar);
                            Logging.Write(Colors.Coral, "Always use Talent Divine Star");
                            return true;
                        }
                    }
                    break;
                case "Halo" :
                    if (PasteurSettings.myPrefs.chckTier6 && IsTargetBoss())
                    {
                        if (SpellManager.CanCast(mySpellInts.halo) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.halo);
                            Logging.Write(Colors.Coral, "Talent Halo on Boss");
                            return true;
                        }
                    }
                    else if (!PasteurSettings.myPrefs.chckTier6)
                    {
                        if (SpellManager.CanCast(mySpellInts.halo) && !SpellManager.GlobalCooldown)
                        {
                            SpellManager.Cast(mySpellInts.halo);
                            Logging.Write(Colors.Coral, "Always use Talent Halo");
                            return true;
                        }
                    }
                    break;
            }
            return false;
        }

        #endregion Talents

        #region Priest Buffs
        public bool PowerWordFortitude()
        {
            
            if (!Me.HasAura(mySpellInts.PWF) 
                && SpellManager.CanCast(mySpellInts.PWF) 
                && !Me.Mounted
                && LastSpell != "PWF")
            {
                Me.Target();
                SpellManager.Cast(mySpellInts.PWF);
                Logging.Write(Colors.LightBlue, "Self Buffing Power Word Fortitude");
                LastSpell = "PWF";
                Me.ClearTarget();
                return true;
            }
            return false;
        }
        public bool InnerFire()
        {
            if (!Me.HasAura(mySpellInts.InFi) 
                && SpellManager.CanCast(mySpellInts.InFi) 
                && !Me.Mounted
                && LastSpell != "InFi")
            {
                SpellManager.Cast(mySpellInts.InFi);
                Logging.Write(Colors.LightBlue, "Buffing Inner Fire");
                LastSpell = "InFi";
                return true;
            }
            return false;
        }
        public bool ShadowForm()
        {
            if (!Me.HasAura(mySpellInts.SF) 
                && SpellManager.CanCast(mySpellInts.SF)
                && LastSpell != "SF")
            {
                SpellManager.Cast(mySpellInts.SF);
                Logging.Write(Colors.LightBlue, "Shadow Form");
                LastSpell = "SF";
                return true;
            }
            return false;
        }
        #endregion Priest Buffs

        #region CastSpell Method

        public bool CastSpell(string spellName, WoWPlayer target)
        {
            if (SpellManager.CanCast(spellName, target) && !SpellManager.GlobalCooldown && !Me.IsCasting)
            {
                if (target == Me)
                {
                    return false;
                }
                else
                {
                    SpellManager.Cast(spellName, target);
                    return true;
                }
            }
            return false;
        }


        public bool CastSpell(string spellName)
        {
            if (SpellManager.CanCast(spellName) && !SpellManager.GlobalCooldown && !Me.IsCasting)
            {
                SpellManager.Cast(spellName);
                return true;
            }
            return false;
        }

        public bool CastSpell(int spellID)
        {
            if (SpellManager.CanCast(spellID) && !SpellManager.GlobalCooldown && !Me.IsCasting)
            {
                SpellManager.Cast(spellID);
                return true;
            }
            return false;
        }
      #endregion CastSpell Methods

		#region AddCounting
        public static bool Adds()
        {

            List<WoWUnit> mobList = ObjectManager.GetObjectsOfType<WoWUnit>(false).FindAll(unit =>
                unit.Guid != Me.Guid
                && unit.IsAlive
                && unit.IsHostile
                && unit.Attackable
                && !unit.IsTotem
                && !unit.IsFriendly
                && (unit.Location.Distance(Me.CurrentTarget.Location) <= 10 || unit.Location.Distance2D(Me.CurrentTarget.Location) <= 10));

            if (mobList.Count >= PasteurSettings.myPrefs.Aoe)
            {
                return true;
            }
            return false;

        }
        public int mobCounting
        {
            get
            {
                List<WoWUnit> mobList = ObjectManager.GetObjectsOfType<WoWUnit>(false).FindAll(unit =>
                unit.Guid != Me.Guid
                && unit.IsAlive
                && unit.IsHostile
                && unit.Attackable
                && !unit.IsTotem
                && !unit.IsFriendly
                && (unit.Location.Distance(Me.CurrentTarget.Location) <= 10 || unit.Location.Distance2D(Me.CurrentTarget.Location) <= 10));
                return mobList.Count;
            }
        }
        #endregion AddCounting

        #region Mana Regen

        public bool FiendBinder()
        {
            if (SpellManager.CanCast(mySpellInts.shadowfiend) && !SpellManager.GlobalCooldown
                && Me.ManaPercent <= PasteurSettings.myPrefs.ShadowfeindMindbender)
            {
                SpellManager.Cast(mySpellInts.shadowfiend);
                Logging.Write(Colors.LightCyan, "Shadow Fiend Mana Regen");
                return true;
            }
            else if (Me.ManaPercent < 40 && SpellManager.CanCast(mySpellInts.MiB) && !SpellManager.GlobalCooldown)
            {
                SpellManager.Cast(mySpellInts.MiB);
                Logging.Write(Colors.LightCyan, "Mindbender Mana Regen");
                return true;
            }
            return false;
        }
        public bool Dispersion()
        {
            if (SpellManager.CanCast(mySpellInts.DisP) && !SpellManager.GlobalCooldown
                && Me.ManaPercent <= PasteurSettings.myPrefs.dispersion)
            {
                SpellManager.Cast(mySpellInts.DisP);
                Logging.Write(Colors.LightCyan, "Dispersion for Mana Regen");
                return true;
            }
            return false;
        }

        #endregion Mana Regen

        #region Self Healing
        public bool PowerWordShield()
        {
            if (SpellManager.CanCast(mySpellInts.PWS) && !SpellManager.GlobalCooldown
                && !Me.HasAura(mySpellInts.PWS)
                && Me.HealthPercent <= PasteurSettings.myPrefs.pws)
            {
                SpellManager.Cast(mySpellInts.PWS);
                Logging.Write(Colors.PaleGreen, "Power Word Shield");
                return true;
            }
            return false;
        }
        public bool VampiricEmbrace()
        {
            if (SpellManager.CanCast(mySpellInts.VE) && !SpellManager.GlobalCooldown 
                && Me.HealthPercent <= 60)
            {
                SpellManager.Cast(mySpellInts.VE);
                Logging.Write(Colors.PaleGreen, "Vampiric Embrace");
                return true;
            }
            return false;
        }
        public bool Renew()
        {
            if (SpellManager.CanCast(mySpellInts.renew) && !SpellManager.GlobalCooldown
                && Me.HealthPercent <= PasteurSettings.myPrefs.renew
                && !Me.HasAura(mySpellInts.renew))
            {
                SpellManager.Cast(mySpellInts.renew);
                Logging.Write(Colors.PaleGreen, "Renew");
                return true;
            }
            return false;
        }
        public bool FlashHeal()
        {
            if (SpellManager.CanCast(mySpellInts.flashheal) && !SpellManager.GlobalCooldown
                && Me.HealthPercent <= PasteurSettings.myPrefs.flash
                && Me.ManaPercent >= 10)
            {
                SpellManager.Cast(mySpellInts.flashheal);
                Logging.Write(Colors.PaleGreen, "Flash Heal");
                return true;
            }
            return false;
        }
        #endregion Self Healing
        #region Kind of Target
        private bool IsTargetBoss()
        {
            if (Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.WorldBoss) 
            { 
                return true;
            }
            else if(Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.Elite
                && Me.CurrentTarget.MaxHealth >= PasteurSettings.myPrefs.likebosses) 
            {
                return true;
            }
            else if(Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.Elite
                && Me.CurrentTarget.Level >= Me.Level && (!Me.GroupInfo.IsInParty
                || !Me.IsInInstance))
            {
                return true;
            }
            else if (Me.CurrentTarget.Name.Contains("Training Dummy"))
            {
                return true;
            }

            else return false;
        }
        
        #endregion Kind of Target
        #region Movement
        WoWPoint attackPoint
        {
            get
            {
                if (Me.GotTarget && SpellManager.Spells.ContainsKey(welkeSpell))
                {
                    return WoWMovement.CalculatePointFrom(Me.CurrentTarget.Location, (float)SpellManager.Spells[welkeSpell].MaxRange - 3);
                }
                else
                {
                    WoWPoint noSpot = new WoWPoint();
                    return noSpot;
                }
            }
        }
        #endregion Movement
        #region Trinkets
        public bool Trinket1()
        {
            switch (PasteurSettings.myPrefs.Trinket1)
            {
                case "boss" :
                    if(IsTargetBoss()) 
                    {
                        myTrinkets.UseTrinket1();
                    }
                    break;
                case "always" :
                    myTrinkets.UseTrinket1();
                    break;
            }
            return false;
        }
        public bool Trinket2()
        {
            switch (PasteurSettings.myPrefs.Trinket2)
            {
                case "boss":
                    if (IsTargetBoss())
                    {
                        myTrinkets.UseTrinket2();
                    }
                    break;
                case "always":
                    myTrinkets.UseTrinket2();
                    break;
            }
            return false;
        }
        #endregion Trinkets

        #region HaveMindSear
        public bool haveMS
        {
            get
            {
                if (Adds() && Me.Level >= 74)
                {
                    return true;
                }
                else return false;
            }
        }
        #endregion HaveMindSear
        #region targettest
        public static void EnsureTarget()
        {
            if (StyxWoW.Me.IsInInstance &&
                TankManager.TargetingTimer.IsFinished && StyxWoW.Me.Combat && TankManager.Instance.FirstUnit != null &&
                (StyxWoW.Me.CurrentTarget == null || StyxWoW.Me.CurrentTarget != TankManager.Instance.FirstUnit))
            {
                Logging.Write("Targeting first unit of TankTargeting");
                TankManager.Instance.FirstUnit.Target();
                TankManager.TargetingTimer.Reset();
            }

            WoWObject ctx = GatherTarget();
            if (ctx != null)
            {
                Logging.Write("Current target is not the best target. Switching to " + ctx + "!");
                ((WoWUnit)ctx).Target();
            }

            if (StyxWoW.Me.CurrentTarget == null || StyxWoW.Me.CurrentTarget.IsDead)
            {
                ctx = GatherTarget2();
                if (ctx != null)
                {
                    Logging.Write("Currect target is invalid. Switching to " + ctx + "!");
                    ((WoWUnit)ctx).Target();
                }
            }
        }

        private static WoWObject GatherTarget2()
        {
            // If we have a RaF leader, then use its target.
            var rafLeader = RaFHelper.Leader;
            if (rafLeader != null && rafLeader.IsValid && !rafLeader.IsMe && rafLeader.Combat &&
                rafLeader.CurrentTarget != null && rafLeader.CurrentTarget.IsAlive && !Blacklist.Contains(rafLeader.CurrentTarget))
            {
                return rafLeader;
            }

            // Check bot poi.
            if (BotPoi.Current.Type == PoiType.Kill)
            {
                var unit = BotPoi.Current.AsObject as WoWUnit;

                if (unit != null && unit.IsAlive && !unit.IsMe && !Blacklist.Contains(unit))
                {
                    return unit;
                }
            }

            // Does the target list have anything in it? And is the unit in combat?
            // Make sure we only check target combat, if we're NOT in a BG. (Inside BGs, all targets are valid!!)
            var firstUnit = Targeting.Instance.FirstUnit;
            if (firstUnit != null && firstUnit.IsAlive && !firstUnit.IsMe && firstUnit.Combat &&
                !Blacklist.Contains(firstUnit))
            {
                return firstUnit;
            }

            // Cache this query, since we'll be using it for 2 checks. No need to re-query it.
            var agroMob =
                ObjectManager.GetObjectsOfType<WoWUnit>(false, false).
                    Where(p => !Blacklist.Contains(p) && p.IsHostile && !p.IsOnTransport && !p.IsDead &&
                                !p.Mounted && p.DistanceSqr <= 70 * 70 && p.Combat).
                    OrderBy(u => u.DistanceSqr).
                    FirstOrDefault();

            if (agroMob != null)
            {
                // Return the closest one to us
                return agroMob;
            }

            // And there's nothing left, so just return null, kthx.
            return null;
        }

        private static WoWObject GatherTarget()
        {
            // No target switching for tanks. They check for their own stuff above.
            if (StyxWoW.Me.IsInInstance)
                return null;
            // Go below if current target is null or dead. We have other checks to deal with that
            if (StyxWoW.Me.CurrentTarget == null || StyxWoW.Me.CurrentTarget.IsDead)
                return null;
            // If the current target is in combat or has aggro towards us, it should be a valid target.
            if (StyxWoW.Me.CurrentTarget != null && (StyxWoW.Me.CurrentTarget.Combat || StyxWoW.Me.CurrentTarget.Aggro))
                return null;
            if (BotPoi.Current.Type == PoiType.Kill)
            {
                var obj = BotPoi.Current.AsObject;

                if (obj != null)
                {
                    if (StyxWoW.Me.CurrentTarget != obj)
                        return obj;
                }
            }
            // Make sure we have the proper target from Targeting. 
            // The Botbase should give us the best target in targeting.
            var firstUnit = Targeting.Instance.FirstUnit;

            if (firstUnit != null)
            {
                if (StyxWoW.Me.CurrentTarget != firstUnit)
                    return firstUnit;
            }
            return null;
        }

        private static WoWPoint CalculatePointBehindTarget()
        {
            return
                StyxWoW.Me.CurrentTarget.Location.RayCast(
                    StyxWoW.Me.CurrentTarget.Rotation + WoWMathHelper.DegreesToRadians(150), MeleeRange - 2f);
        }
        public static float MeleeRange
        {
            get
            {
                if (StyxWoW.Me.CurrentTargetGuid == 0)
                    return 0f;

                if (StyxWoW.Me.CurrentTarget.IsPlayer)
                    return 3.5f;

                return Math.Max(5f, StyxWoW.Me.CombatReach + 1.3333334f + StyxWoW.Me.CurrentTarget.CombatReach);
            }
        }
        #endregion

    }
}
